package com.egao.wecanfly;

/**
 * @author : Doman
 * @date : 2019-1-22 上午11:17:13
 * @version ：
 */


import com.egao.common.core.damon.GuavaUitl;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.FileResourceLoader;

import java.io.*;
import java.sql.ResultSet;
import java.util.*;

/**
 * Velocity生成静态页面
 * @author wanghjbuf
 */
public class WeCanFly {
	private static final String DEF_ENCODING = "utf-8";

	public static void main(String []args) throws Exception{

		WeCanFly w = new WeCanFly();
		w.generatorFileforBeetl();
	}

	public void generatorFileforBeetl() throws Exception{
		Properties prop = PropertiesLoad.getProperties();
		String openfile = prop.getProperty("open.source");
		String cmdDir[] = { "explorer.exe", openfile };
		Runtime.getRuntime().exec(cmdDir);
		String database = prop.getProperty("database");
		String tableName = prop.getProperty("tableName");
		String tableNameJavaEntity = prop.getProperty("tableNameJavaEntity");
		WeCanFly generHtmlForVelocity = new WeCanFly();
		StringBuffer sql = new StringBuffer("select table_name,table_comment,create_time from information_schema.TABLES ");
		sql.append(" where TABLE_SCHEMA='"+database+"' ");
		sql.append(" and instr(table_name,\""+tableName+"\")>0 ");
		JDBCHelperWeCanFly dbHelper = new JDBCHelperWeCanFly();
		ResultSet resultSet = dbHelper.executeResultSet(sql.toString());

		String tableComment = "";String create_time = "";
		if (resultSet.next())
		{
			tableName = resultSet.getString("table_name");
			tableComment = resultSet.getString("table_comment");
			create_time = resultSet.getString("create_time");
			if(create_time.length()>2){
				create_time = create_time.substring(0,create_time.length()-2);
			}
		}
		sql = new StringBuffer("select COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT ");
		sql.append("from information_schema.COLUMNS ");
		sql.append("where table_name = '"+tableName+"' and table_schema = '"+database+"'");
		sql.append(" order by ORDINAL_POSITION ");
		resultSet = dbHelper.executeResultSet(sql.toString());
		List<String> columnNameList;List<String> columnNameNoCAMELList;List<String> dataTypeList;List<String> columnCommentList;
		columnNameList = new ArrayList<String>();columnNameNoCAMELList = new ArrayList<String>();dataTypeList = new ArrayList<String>();columnCommentList = new ArrayList<String>();
		while (resultSet.next())
		{
			columnNameList.add(GuavaUitl.LOWER_CAMEL(resultSet.getString("COLUMN_NAME")));
			columnNameNoCAMELList.add(resultSet.getString("COLUMN_NAME"));
			dataTypeList.add(resultSet.getString("DATA_TYPE"));
			columnCommentList.add(resultSet.getString("COLUMN_COMMENT"));
		}
		dbHelper.close();

		String root = System.getProperty("user.dir")
				+ File.separator+"src"+ File.separator+"test"
				+ File.separator+"java"+ File.separator+"com"
				+ File.separator+"egao" + File.separator+"wecanfly"
				+ File.separator+"template";
		FileResourceLoader resourceLoader = new FileResourceLoader(root,"utf-8");
		Configuration cfg = Configuration.defaultConfiguration();
		GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);


		createFile(gt,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);


		System.out.println("代码生成 成功");
	}
	public void createFile(GroupTemplate gt,List<String> columnNameList,List<String> columnNameNoCAMELList,
						   List<String> dataTypeList,List<String> columnCommentList,
						   String tableNameJavaEntity,String tableName,String tableComment) throws Exception{
		Properties prop = PropertiesLoad.getProperties();
		String tableNameJavaEntityDx = dx(tableNameJavaEntity);
		String packages = prop.getProperty("packages");
		String writesource = prop.getProperty("write.source");
		String writepackage = prop.getProperty("write.source.package");
		String writepage = prop.getProperty("write.source.page");
		makedir();

		Template t = gt.getTemplate("/Controller.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/controller/" + tableNameJavaEntityDx+"Controller.java");

		t = gt.getTemplate("/Service.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/service/" + tableNameJavaEntityDx+"Service.java");

		t = gt.getTemplate("/ServiceImpl.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/service/impl/" + tableNameJavaEntityDx+"ServiceImpl.java");

		t = gt.getTemplate("/Biz.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/biz/" + tableNameJavaEntityDx+"Biz.java");

		t = gt.getTemplate("/BizImpl.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/biz/impl/" + tableNameJavaEntityDx+"BizImpl.java");

/*
		t = gt.getTemplate("/Mapper.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/mapper/" + tableNameJavaEntityDx+"Mapper.java");

		t = gt.getTemplate("/MapperXml.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/mapper/xml/" + tableNameJavaEntityDx+"Mapper.xml");
*/

		t = gt.getTemplate("/Entity.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+writepackage+packages+"/entity/" + tableNameJavaEntityDx+".java");

		t = gt.getTemplate("/SpaPage.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource + tableNameJavaEntity+".html");

//		t = gt.getTemplate("/list.txt");
//		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
//		writeFile(t, writesource+writepage+packages+"/" + tableNameJavaEntity+".html");

		t = gt.getTemplate("/Sql.txt");
		initData(t,columnNameList,columnNameNoCAMELList,dataTypeList,columnCommentList,tableNameJavaEntity,tableName,tableComment);
		writeFile(t, writesource+"sql.txt");

	}

	public void writeFile(Template t, String fileName) throws Exception{
		String str = t.render();
//		System.out.println(str);
		BufferedWriter bufferedWriter = null;
		bufferedWriter = new BufferedWriter(new FileWriter(fileName));
		bufferedWriter.write(str);
		if (bufferedWriter != null) {
			bufferedWriter.flush();
			bufferedWriter.close();
		}
	}

	/**
	 * 初始化VelocityContext
	 * @author wanghjbuf
	 */
	public void initData(Template t,List<String> columnNameList,
						 List<String> columnNameNoCAMELList,List<String> dataTypeList,
			 List<String> columnCommentList,String tableNameJavaEntity,
			 String tableName, String tableComment) throws Exception{
		List<String> dataTypeListJava = new ArrayList<String>();
		List<String> dataTypeListJavaReal = new ArrayList<String>();
		List<String> columnNameDxList = new ArrayList<String>();
		String hasDate = "no";
		for (int i = 0; i < dataTypeList.size(); i++) {
			String dataType =  dataTypeList.get(i);
			String columnName = columnNameList.get(i);
			if(!dataType.equals("")){
				if(dataType.equals("varchar")){
					dataTypeListJava.add("String");
					dataTypeListJavaReal.add("String");
				} else if(dataType.equals("int")||dataType.equals("smallint")){
					dataTypeListJava.add("Integer");
					dataTypeListJavaReal.add("Integer");
				} else if(dataType.equals("datetime")||dataType.equals("date")){
					dataTypeListJava.add("String");
					dataTypeListJavaReal.add("Date");
					if(!columnName.equals("create_time") && !columnName.equals("update_time")){
						hasDate="yes";
					}
				}else {
					dataTypeListJava.add("String");
					dataTypeListJavaReal.add("String");
				}
			} else {
				dataTypeListJava.add("String");
				dataTypeListJavaReal.add("String");
			}
		}
		for (int i = 0; i < columnNameList.size(); i++) {
			String columnNameDx =  columnNameList.get(i);
			columnNameDxList.add(dx(columnNameDx));
		}

		Properties prop = PropertiesLoad.getProperties();
		String packages = prop.getProperty("packages");
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("packages", packages);
		map.put("hasDate", hasDate);
		map.put("now", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		map.put("tableName", tableName);
		map.put("tableNameJavaEntity", tableNameJavaEntity);
		map.put("tableNameJavaEntityDx", dx(tableNameJavaEntity));
		map.put("tableComment", tableComment);
		map.put("sqlTable", tableNameJavaEntity.substring(0,1));
		map.put("columnNameNoCAMELList", columnNameNoCAMELList);
		map.put("columnNameList", columnNameList);
		map.put("columnNameDxList", columnNameDxList);
		map.put("dataTypeListJava", dataTypeListJava);
		map.put("dataTypeListJavaReal", dataTypeListJavaReal);
		map.put("columnCommentList", columnCommentList);
		map.put("permissionAdd", "<% if(so.hasPermission(\""+packages+":"+tableNameJavaEntity+":save\")){ %>");
		map.put("permissionUpdate", "<% if(so.hasPermission(\""+packages+":"+tableNameJavaEntity+":update\")){ %>");
		map.put("permissionDelete", "<% if(so.hasPermission(\""+packages+":"+tableNameJavaEntity+":remove\")){ %>");
		map.put("permissionEnd", "<% } %>");
//		map.put("listPageIncludecss", "<% include(\"../layout/css.html\"){} %>");
//		map.put("listPageIncludejs", "<:include file=\"../common/js.html\"/>");
		t.binding("d",map);
	}

	public String dx(String nameString){
		String str1=nameString.substring(0,1).toUpperCase().concat(nameString.substring(1));
		return str1;
	}

	public void makedir(){
		Properties prop = PropertiesLoad.getProperties();
		String packages = prop.getProperty("packages");
		String writeSource = prop.getProperty("write.source");

		delAllFile(writeSource);

		File file = new File(writeSource+"main/java/com/egao/"+packages+"/controller");
		if(!file.exists()){ file.mkdirs();}
		file = new File(writeSource+"main/java/com/egao/"+packages+"/entity");
		if(!file.exists()){ file.mkdirs();}
		file = new File(writeSource+"main/java/com/egao/"+packages+"/service/impl");
		if(!file.exists()){ file.mkdirs();}
		file = new File(writeSource+"main/java/com/egao/"+packages+"/biz/impl");
		if(!file.exists()){ file.mkdirs();}
		file = new File(writeSource+"main/java/com/egao/"+packages+"/mapper/xml");
		if(!file.exists()){ file.mkdirs();}
		file = new File(writeSource+"main/resources/templates/"+packages);
		if(!file.exists()){ file.mkdirs();}
	}

	// 删除指定文件夹下所有文件
	// param path 文件夹完整绝对路径
	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
				delFolder(path + "/" + tempList[i]);// 再删除空文件夹
				flag = true;
			}
		}
		return flag;
	}
	// 删除文件夹
	// param folderPath 文件夹完整绝对路径
	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath); // 删除完里面所有内容
			String filePath = folderPath;
			filePath = filePath.toString();
			File myFilePath = new File(filePath);
			myFilePath.delete(); // 删除空文件夹
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取Velocity写入流
	 * @author wanghjbuf
	 */
	public BufferedWriter getWriterStream(String name) throws Exception{
		try{
			FileOutputStream fos = new FileOutputStream(name);
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, DEF_ENCODING));
			return writer;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
}